package com.yugao.fintech.framework.database.flyway;

import com.yugao.fintech.framework.core.constant.LyCoreConstants;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.DurationUnit;

import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * Configuration properties for Flyway database migrations.
 */
@Data
@ConfigurationProperties(prefix = LyCoreConstants.PROPERTIES_PRE_NO_POINT)
public class MyFlywayProperties {
    private List<Properties> flyways = Collections.emptyList();

    @Data
    public static class Properties {
        /**
         * 指定数据源, 需要配合draper-starter-dynamic-datasource依赖使用
         */
        private String dataSource;
        /**
         * Whether to enable flyway.
         */
        private boolean enabled = true;

        /**
         * Whether to fail if a location of migration scripts doesn't exist.
         */
        private Boolean failOnMissingLocations;

        /**
         * Locations of migrations scripts. Can contain the special "{vendor}" placeholder to
         * use vendor-specific locations.
         */
        private List<String> locations = new ArrayList<>(Collections.singletonList("classpath:db/migration"));

        /**
         * Encoding of SQL migrations.
         */
        private Charset encoding = StandardCharsets.UTF_8;

        /**
         * Maximum number of retries when attempting to connect to the database.
         */
        private int connectRetries;

        /**
         * Maximum time between retries when attempting to connect to the database. If a
         * duration suffix is not specified, seconds will be used.
         */
        @DurationUnit(ChronoUnit.SECONDS)
        private Duration connectRetriesInterval;

        /**
         * Maximum number of retries when trying to obtain a lock.
         */
        private Integer lockRetryCount;

        /**
         * Default schema name managed by Flyway (case-sensitive).
         */
        private String defaultSchema;

        /**
         * Scheme names managed by Flyway (case-sensitive).
         */
        private List<String> schemas = new ArrayList<>();

        /**
         * Whether Flyway should attempt to create the schemas specified in the schemas
         * property.
         */
        private Boolean createSchemas = true;

        /**
         * Name of the schema history table that will be used by Flyway.
         */
        private String table = "flyway_schema_history";

        /**
         * Tablespace in which the schema history table is created. Ignored when using a
         * database that does not support tablespaces. Defaults to the default tablespace of
         * the connection used by Flyway.
         */
        private String tablespace;

        /**
         * Description to tag an existing schema with when applying a baseline.
         */
        private String baselineDescription = "<< Flyway Baseline >>";

        /**
         * Version to tag an existing schema with when executing baseline.
         */
        private String baselineVersion = "1";

        /**
         * Username recorded in the schema history table as having applied the migration.
         */
        private String installedBy;

        /**
         * Placeholders and their replacements to apply to sql migration scripts.
         */
        private Map<String, String> placeholders = new HashMap<>();

        /**
         * Prefix of placeholders in migration scripts.
         */
        private String placeholderPrefix = "${";

        /**
         * Suffix of placeholders in migration scripts.
         */
        private String placeholderSuffix = "}";

        /**
         * Separator of default placeholders.
         */
        private String placeholderSeparator;

        /**
         * Perform placeholder replacement in migration scripts.
         */
        private Boolean placeholderReplacement = true;

        /**
         * File name prefix for SQL migrations.
         */
        private String sqlMigrationPrefix = "V";

        /**
         * File name suffix for SQL migrations.
         */
        private List<String> sqlMigrationSuffixes = new ArrayList<>(Collections.singleton(".sql"));

        /**
         * File name separator for SQL migrations.
         */
        private String sqlMigrationSeparator = "__";

        /**
         * File name prefix for repeatable SQL migrations.
         */
        private String repeatableSqlMigrationPrefix = "R";

        /**
         * Target version up to which migrations should be considered.
         */
        private String target;

        /**
         * Login user of the database to migrate.
         */
        private String user;

        /**
         * Login password of the database to migrate.
         */
        private String password;

        /**
         * Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
         */
        private String driverClassName;

        /**
         * JDBC url of the database to migrate. If not set, the primary configured data source
         * is used.
         */
        private String url;

        /**
         * SQL statements to execute to initialize a connection immediately after obtaining
         * it.
         */
        private List<String> initSqls = new ArrayList<>();

        /**
         * Whether to automatically call baseline when migrating a non-empty schema.
         */
        private Boolean baselineOnMigrate;

        /**
         * Whether to disable cleaning of the database.
         */
        private Boolean cleanDisabled;

        /**
         * Whether to automatically call clean when a validation error occurs.
         */
        private Boolean cleanOnValidationError;

        /**
         * Whether to group all pending migrations together in the same transaction when
         * applying them.
         */
        private Boolean group;

        /**
         * Whether to allow mixing transactional and non-transactional statements within the
         * same migration.
         */
        private Boolean mixed;

        /**
         * Whether to allow migrations to be run out of order.
         */
        private Boolean outOfOrder;

        /**
         * Whether to skip default callbacks. If true, only custom callbacks are used.
         */
        private Boolean skipDefaultCallbacks;

        /**
         * Whether to skip default resolvers. If true, only custom resolvers are used.
         */
        private Boolean skipDefaultResolvers;

        /**
         * Whether to validate migrations and callbacks whose scripts do not obey the correct
         * naming convention.
         */
        private Boolean validateMigrationNaming = false;

        /**
         * Whether to automatically call validate when performing a migration.
         */
        private Boolean validateOnMigrate = true;

        /**
         * Whether to batch SQL statements when executing them. Requires Flyway Teams.
         */
        private Boolean batch;

        /**
         * File to which the SQL statements of a migration dry run should be output. Requires
         * Flyway Teams.
         */
        private File dryRunOutput;

        /**
         * Rules for the built-in error handling to override specific SQL states and error
         * codes. Requires Flyway Teams.
         */
        private String[] errorOverrides;

        /**
         * Licence key for Flyway Teams.
         */
        private String licenseKey;

        /**
         * Whether to enable support for Oracle SQL*Plus commands. Requires Flyway Teams.
         */
        private Boolean oracleSqlplus;

        /**
         * Whether to issue a warning rather than an error when a not-yet-supported Oracle
         * SQL*Plus statement is encountered. Requires Flyway Teams.
         */
        private Boolean oracleSqlplusWarn;

        /**
         * Whether to stream SQL migrations when executing them. Requires Flyway Teams.
         */
        private Boolean stream;

        /**
         * File name prefix for undo SQL migrations. Requires Flyway Teams.
         */
        private String undoSqlMigrationPrefix;

        /**
         * Migrations that Flyway should consider when migrating or undoing. When empty all
         * available migrations are considered. Requires Flyway Teams.
         */
        private String[] cherryPick;

        /**
         * Properties to pass to the JDBC driver. Requires Flyway Teams.
         */
        private Map<String, String> jdbcProperties = new HashMap<>();

        /**
         * Path of the Kerberos config file. Requires Flyway Teams.
         */
        private String kerberosConfigFile;

        /**
         * Path of the Oracle Kerberos cache file. Requires Flyway Teams.
         */
        private String oracleKerberosCacheFile;

        /**
         * Location of the Oracle Wallet, used to sign-in to the database automatically.
         * Requires Flyway Teams.
         */
        private String oracleWalletLocation;

        /**
         * Whether Flyway should output a table with the results of queries when executing
         * migrations. Requires Flyway Teams.
         */
        private Boolean outputQueryResults;

        /**
         * Path to the SQL Server Kerberos login file. Requires Flyway Teams.
         */
        private String sqlServerKerberosLoginFile;

        /**
         * Whether Flyway should skip executing the contents of the migrations and only update
         * the schema history table. Requires Flyway teams.
         */
        private Boolean skipExecutingMigrations;

        /**
         * Ignore migrations that match this comma-separated list of patterns when validating
         * migrations. Requires Flyway Teams.
         */
        private List<String> ignoreMigrationPatterns;

        /**
         * Whether to attempt to automatically detect SQL migration file encoding. Requires
         * Flyway Teams.
         */
        private Boolean detectEncoding;

        /**
         * Filename prefix for baseline migrations. Requires Flyway Teams.
         */
        private String baselineMigrationPrefix;

        /**
         * Prefix of placeholders in migration scripts.
         */
        private String scriptPlaceholderPrefix;

        /**
         * Suffix of placeholders in migration scripts.
         */
        private String scriptPlaceholderSuffix;
    }

}
